#!/usr/bin/env python

"""Helpers for namomi client and server."""


__author__ = "Crabhi"
__version__ = "$Revision$"

import pygame, os.path
import hashlib
import unittest

try:
    from os import urandom
    random = lambda: urandom(20)
except ImportError:
    from random import random


def load_image(fullname, colorkey=None, transparency=False):
    fullname = os.path.join("img", fullname)
    image = pygame.image.load(fullname)
    image = image.convert() if not transparency else image.convert_alpha()
    if colorkey is not None:
        if colorkey is -1:
            colorkey = image.get_at((0, 0))
        image.set_colorkey(colorkey, pygame.RLEACCEL)
    return image
    

def random_digest():
    string = str(random())
    return hashlib.md5(string).hexdigest()


class DictList(dict):
    """Dictionary with numeric indices having the append and index methods, 
    setting is not allowed (instead, delete the element and append the new one
    to get another id)"""
    def __init__(self, *args):
        dict.__init__(self, *args)
        self.max_id = len(self) - 1
    
    def append(self, member):
        self.max_id += 1
        dict.__setitem__(self, self.max_id, member)
        return self.max_id

    def __contains__(self, item):
        for j in self.itervalues():
            if item == j:
                return True
        return False
    
    def __len__(self):
        return len(self.values())
    
    def __getitem__(self, key):
        if type(key) is not int:
            raise TypeError("Only integer ids supported")
        try:
            return dict.__getitem__(self, key)
        except KeyError:
            raise IndexError("Item with id %d not in the list." % key)

    def __delitem__(self, key):
        if type(key) is not int:
            raise TypeError("Only integer ids supported")
        try:
            dict.__delitem__(self, key)
        except KeyError:
            raise IndexError("Item with id %d not in the list." % key)
    
    def __setitem__(self, key, value):
        raise NotImplementedError
    
    def __iter__(self):
        return dict.iteritems(self)

class TestDictList(unittest.TestCase):
    def setUp(self):
        self.dl = DictList()
        self.id1 = self.dl.append("a")
        self.id2 = self.dl.append("b")
        self.id3 = self.dl.append("a")
        self.id4 = self.dl.append("c")
        self.id5 = self.dl.append("d")
        

    def test_ids(self):
        self.assert_([self.id1,
                    self.id2,
                    self.id3,
                    self.id4,
                    self.id5] == range(5))
    
    def test_contains(self):
        self.assert_("a" in self.dl)
        self.assert_("b" in self.dl)
        self.assert_("c" in self.dl)
        self.assert_("d" in self.dl)
        self.assert_(0 not in self.dl)
        self.assert_("e" not in self.dl)
        del self.dl[0]
        self.assert_("a" in self.dl)
        del self.dl[2]
        self.assert_("a" not in self.dl)
    
    def test_len(self):
        self.assertEqual(len(self.dl), 5)
        del self.dl[3]
        self.assertEqual(len(self.dl), 4)
        self.id5 = self.dl.append("d")
        self.assertEqual(len(self.dl), 5)
        
    def test_access(self):
        self.assertEqual(self.dl[1], "b")
        del self.dl[1]
        try:
            self.dl[1]
        except IndexError:
            pass
        else:
            self.fail()
        try:
            self.dl[5]
        except IndexError:
            pass
        else:
            self.fail()
        
        self.dl.append(3)
        self.assertEqual(self.dl[5], 3)
        try:
            del self.dl[-1]
        except IndexError:
            pass
        else:
            self.fail()
    
    def test_set(self):
        try:
            self.dl[1] = 3
        except NotImplementedError:
            pass
        else:
            self.fail()
if __name__ == "__main__":
    unittest.main()
